package cn.lg.soar.database.base.entity;

import cn.lg.soar.common.util.data.DataUtil;
import cn.lg.soar.common.util.data.StringUtil;
import com.fasterxml.jackson.annotation.JsonIgnore;
import org.springframework.util.StringUtils;

import java.io.Serializable;
import java.util.Collection;
import java.util.stream.Collectors;

/**
 * 树形数据，使用id链实现
 * @author luguoxiang
 * 开源项目：https://gitee.com/lgx1992/lg-soar 求star！请给我star！请帮我点个star！
 */
public interface IPathTreeEntity<ID extends Serializable> extends ITreeEntity<ID> {

    String ANCESTOR_LINK = "ancestor_link";
    String SORT = "sort";
    String ANCESTOR_LINK_JOIN = ">";

    String getAncestorLink();

    void setAncestorLink(String ancestorLink);

    Integer getSort();

    void setSort(Integer sort);

    @JsonIgnore
    default void setParent(IPathTreeEntity<ID> parent) {
        this.setParentId((ID)parent.primaryKey());
        StringBuilder sb = new StringBuilder(64);
        if(StringUtils.hasText(parent.getAncestorLink())){
            sb.append(parent.getAncestorLink());
        }
        sb.append(this.getParentId().toString()).append(IPathTreeEntity.ANCESTOR_LINK_JOIN);
        this.setAncestorLink(sb.toString());
    }

    /**
     * 下级祖先链前缀
     * @return
     */
    default String inferiorsAncestorLinkPrefix() {
        return getAncestorLink() + primaryKey() + ANCESTOR_LINK_JOIN;
    }

    /**
     * 祖先id数组
     * @return
     */
    default String[] ancestorIds() {
        return ancestorLinkToIds(getAncestorLink());
    }

    /**
     * 祖先链转id数组
     * @param ancestorLink
     * @return
     */
    static String[] ancestorLinkToIds(String ancestorLink) {
        if (StringUtil.isBlank(ancestorLink)) {
            return new String[0];
        }
        return ancestorLink.split(IPathTreeEntity.ANCESTOR_LINK_JOIN);
    }

    /**
     * id集合转祖先链
     * @param ids
     * @return
     */
    static String idsToAncestorLink(Collection<? extends Serializable> ids) {
        if (ids == null || ids.isEmpty()) {
            return "";
        }
        return ids.stream()
                .map(Serializable::toString)
                .collect(Collectors.joining(ANCESTOR_LINK_JOIN)) + ANCESTOR_LINK_JOIN;
    }

    /**
     * id数组转祖先链
     * @param ids
     * @return
     */
    static String idsToAncestorLink(String ...ids) {
        return idsToAncestorLink(DataUtil.arrayToList(ids));
    }

    /**
     * id数组转祖先链
     * @param ids
     * @return
     */
    static String idsToAncestorLink(Long ...ids) {
        return idsToAncestorLink(DataUtil.arrayToList(ids));
    }

}
